package com.bingxue.edu.management.generator;

import cn.hutool.core.util.StrUtil;
import com.bingxue.edu.common.enums.CommonStatusEnum;
import com.bingxue.edu.framework.common.model.AuditableEntity;
import com.bingxue.edu.framework.common.model.BaseEntity;
import com.bingxue.edu.framework.common.model.BusinessEntity;
import com.bingxue.edu.framework.mybatis.base.BaseMapper;
import com.bingxue.edu.framework.mybatis.base.BaseService;
import com.mybatisflex.codegen.Generator;
import com.mybatisflex.codegen.config.EntityConfig;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.mybatisflex.codegen.dialect.JdbcTypeMapping;
import com.zaxxer.hikari.HikariDataSource;

import java.sql.Date;
import java.time.LocalDate;

/**
 * 代码生成工具类
 * 基于mybatis-flex的代码生成工具类，用于本地化生成代码，功能较简单，建议使用web在线生成代码
 * @author panbo
 * @since 2024/6/26
 */
public class CodeGenerator {
    private static final String basePackage = "com.bingxue.edu.module";
    private static final String module = "system";
    private static final String tablePrefix = "base_";
    private static final String table = "base_org";
    private static final boolean overwrite = true;


    public static void main(String[] args) {
        // 配置数据源
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/bingxue_v2?remarks=true&useInformationSchema=true&tinyInt1isBit=true&characterEncoding=utf-8");
        dataSource.setUsername("xxx");
        dataSource.setPassword("xxx");

        // 创建生成配置
        GlobalConfig globalConfig = createGlobalConfig();
        Generator generator = new Generator(dataSource, globalConfig);

        // 生成
        generator.generate();
    }

    private static GlobalConfig createGlobalConfig() {
        GlobalConfig globalConfig = new GlobalConfig();

        globalConfig.getPackageConfig()
                .setBasePackage(basePackage + "." + module)
                .setEntityPackage(basePackage + "." + module + ".model.entity");

        globalConfig.getStrategyConfig()
                .setTablePrefix(tablePrefix)
                .setGenerateTable(table)
                .setLogicDeleteColumn("deleted")
                .setIgnoreColumns("create_user", "update_user", "create_time", "update_time", "deleted");

        globalConfig.getTemplateConfig()
                .setEntity("/templates/entity.tpl")
                .setMapper("/templates/mapper.tpl")
                .setService("/templates/service.tpl")
                .setServiceImpl("/templates/serviceImpl.tpl")
                .setController("/templates/controller.tpl");

        globalConfig.getJavadocConfig()
                .setColumnCommentFormat(s -> {
                    if(s.startsWith("enum-")) {
                        return s.replace("enum-", "");
                    }
                    return s;
                });


        globalConfig.enableEntity()
                .setWithSwagger(true)
                .setSwaggerVersion(EntityConfig.SwaggerVersion.DOC)
                .setOverwriteEnable(true)
                .setWithLombok(true)
                .setJdkVersion(17)
                .setImplInterfaces()
                .setSuperClassFactory(table -> {
                    if(table.containsColumn("deleted")) {
                        return BusinessEntity.class;
                    } else if(table.containsColumn("create_time")) {
                        return AuditableEntity.class;
                    } else {
                        return BaseEntity.class;
                    }
                });

        globalConfig.enableMapper()
                .setSuperClass(BaseMapper.class)
                .setMapperAnnotation(true)
                .setOverwriteEnable(overwrite);
        globalConfig.enableService()
                .setSuperClass(BaseService.class)
                .setOverwriteEnable(overwrite);
        globalConfig.enableServiceImpl()
                .setSuperClass(BaseService.class)
                .setOverwriteEnable(overwrite);
        globalConfig.enableController()
                .setOverwriteEnable(overwrite);

        JdbcTypeMapping.registerMapping(Date.class, LocalDate.class);
        JdbcTypeMapping.setTypeMapper((jdbcType, table, column) -> {
            if (column.getName().equals("status")) {
                return CommonStatusEnum.class.getName();
            }
            if (column.getComment().startsWith("enum-")) {
                return "com.bingxue.edu.framework.common.enums." + StrUtil.upperFirst(StrUtil.toCamelCase(column.getName())) + "Enum";
            }
            return null;
        });

        return globalConfig;

    }
}
